﻿using SelfMadeMillionaire.Core.Enums;
using SelfMadeMillionaire.Core.Services;
using SelfMadeMillionaire.Web.Infrastructure.ViewModels.MailingList;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using PagedList;
using SelfMadeMillionaire.Core.Entities;
using SelfMadeMillionaire.Core;
using SelfMadeMillionaire.Web.Infrastructure.ViewModels.Account;

namespace SelfMadeMillionaire.Web.Infrastructure.Controllers.Admin
{
	public class MailingListController : AdminController
	{
		IMailingListService _mailingListService;
		ISubscriberService _subscriberService;
		IPaymentService _paymentService;

		public MailingListController(IMailingListService mailingListService, ISubscriberService subscriberService, IPaymentService paymentService)
		{
			_mailingListService = mailingListService;
			_subscriberService = subscriberService;
			_paymentService = paymentService;
		}

		[HttpGet]
        public ActionResult Index(string firstName, string lastName, ProductType? selectedProduct, string email, int? page, int? paget, string sort)
		{
			int pageIndex = page ?? 1;
            int pageIndexTrans = paget ?? 1;
			int pageSize = 10;

			var model = new MailingListViewModel
			{
				FirstName = firstName,
				LastName = lastName,
				ProductTypes = GetProductTypes(selectedProduct),
				Email = email,
				EditModel = new AdminSubscriberViewModel { IsSMM = true },
                Transactions = _paymentService.GetPayments().ToPagedList(pageIndexTrans, pageSize),
                Page = pageIndex,
                PageT = pageIndexTrans,
                SortOrder = sort
			};

            IEnumerable<Subscriber> list = _mailingListService.GetSubscribers(firstName, lastName, selectedProduct, email);
            if (!string.IsNullOrEmpty(sort))
            {
                string[] sortArr = sort.Split(',');
                if (sortArr[1] == "0")
                {
                    switch (sortArr[0])
                    {
                        case "0":
                            list = list.OrderBy(i => i.FirstName);
                            break;
                        case "1":
                            list = list.OrderBy(i => i.LastName);
                            break;
                        case "2":
                            list = list.OrderBy(i => i.Email);
                            break;
                        case "3":
                            list = list.OrderBy(i => i.IsSMMSubscriber());
                            break;
                        case "4":
                            list = list.OrderBy(i => i.SubscriptionLevelName);
                            break;
                        case "5":
                            list = list.OrderBy(i => !i.MmmUnsubscribed);
                            break;
                        case "6":
                            list = list.OrderBy(i => i.StartDate);
                            break;
                        case "7":
                            list = list.OrderBy(i => i.EndDate);
                            break;
                        case "8":
                            list = list.OrderBy(i => Enum.Parse(typeof(StatusType), i.Status.ToString()));
                            break;
                    }

                }
                else
                {
                    switch (sortArr[0])
                    {
                        case "0":
                            list = list.OrderByDescending(i => i.FirstName);
                            break;
                        case "1":
                            list = list.OrderByDescending(i => i.LastName);
                            break;
                        case "2":
                            list = list.OrderByDescending(i => i.Email);
                            break;
                        case "3":
                            list = list.OrderByDescending(i => i.IsSMMSubscriber());
                            break;
                        case "4":
                            list = list.OrderByDescending(i => i.SubscriptionLevelName);
                            break;
                        case "5":
                            list = list.OrderByDescending(i => !i.MmmUnsubscribed);
                            break;
                        case "6":
                            list = list.OrderByDescending(i => i.StartDate);
                            break;
                        case "7":
                            list = list.OrderByDescending(i => i.EndDate);
                            break;
                        case "8":
                            list = list.OrderByDescending(i => Enum.Parse(typeof(StatusType), i.Status.ToString()));
                            break;
                    }
                }
            }
            model.Subscribers = list.ToPagedList(pageIndex, pageSize);

			if (Request.IsAjaxRequest())
				return PartialView("MailingListTable", model);

			return View(model);
		}

		[HttpGet]
		public PartialViewResult Edit(int? id)
		{
			AdminSubscriberViewModel model = new AdminSubscriberViewModel();
            Subscriber subscriber = null;

            if (id.HasValue)
              subscriber = _subscriberService.Get(id.Value);

            model = new AdminSubscriberViewModel(subscriber);

            return PartialView(model);
		}

		[HttpPost]
		public ActionResult Edit(AdminSubscriberViewModel model)
		{
			if (ModelState.IsValid)
			{
				if (_subscriberService.IsExists(model.Email, model.ID))
					ModelState.AddModelError("Email", "Email already exists");
				else
				{
                    Subscriber subscriber;
                    if (model.ID == 0)
                        subscriber = new Subscriber();
                    else
                        // not all updated fields on form, therefore read fields from db and fill some of them from model
                        subscriber = _subscriberService.Get(model.ID);

                    subscriber.ID = model.ID;
					subscriber.FirstName = model.FirstName;
					subscriber.LastName = model.LastName;
					subscriber.Email = model.Email;
					subscriber.ProductType = (byte)GetProductType(model.IsSMM, model.IsMMM);
                    subscriber.TesterAccount = model.TesterAccount;
                    if (model.ID == 0)
					{
						subscriber.SubscriptionLevel = (byte?)SubscriptionType.Free;
                        subscriber.Status = (byte)StatusType.Active;
						_subscriberService.Add(subscriber);
					}
					else
						_subscriberService.Update(subscriber);

					return Json(new { success = true }, JsonRequestBehavior.AllowGet);
				}
			}

			return PartialView(model);
		}

		[HttpPost]
		public void Delete(int id)
		{
			_subscriberService.Remove(id);
		}

        [HttpGet]
        public PartialViewResult ChangePassword(int id)
        {
            Subscriber subscriber = _subscriberService.Get(id);

            var model = new AdminChangePasswordViewModel
            {
                ID = subscriber.ID
            };

            return PartialView(model);
        }

        [HttpPost]
        public ActionResult ChangePassword(AdminChangePasswordViewModel model)
        {
            if (ModelState.IsValid)
            {
                Subscriber subscriber = _subscriberService.Get(model.ID);
                if (subscriber != null)
                {
                    subscriber.PasswordHash = PasswordUtility.GetPasswordHash(model.Password);
                    _subscriberService.Update(subscriber);
                }
                return Json(new { success = true }, JsonRequestBehavior.AllowGet);
            }

            return PartialView(model);
        }

        [HttpGet]
        public PartialViewResult SubscriptionInfo(int id)
        {
            Subscriber subscriber = _subscriberService.Get(id);

            var model = new SubscriptionInfoViewModel
            {
                ID = id,
                IsMMM = (subscriber.ProductType == (byte)ProductType.MaggiesMoneyMountain),
                IsSMM = (subscriber.ProductType == (byte)ProductType.SelfMadeMillionaire),
                IsMMMSubscribe = !subscriber.MmmUnsubscribed,
                IsSMMSubscribe = !subscriber.SmmUnsubscribed,
                SubscriptionLevel = (SubscriptionType)(subscriber.SubscriptionLevel ?? 0),
                Balance = _paymentService.GetBalance(subscriber.Email),
                ExperationDate = subscriber.EndDate.HasValue ? subscriber.EndDate.Value : subscriber.CreatedDate.AddYears(1),
                ProductList = _subscriberService.GetProducts(subscriber)
            };

            return PartialView(model);
        }

        [HttpGet]
        public PartialViewResult EditSubscriptionInfo(int id)
        {
            Subscriber subscriber = _subscriberService.Get(id);

            var model = new EditSubscriptionInfoViewModel
            {
                ID = id,
                ExpirationDate = subscriber.EndDate
            };

            List<SelectListItem> levels = GetAccessLevels(subscriber.SubscriptionLevel).ToList();
            levels.Insert(0, new SelectListItem() { Text = "(unsubscribed)", Value = "-1" });
            model.ProductTypes = new SelectList(levels, "Value", "Text");

            if ((!subscriber.SmmUnsubscribed) && (subscriber.SubscriptionLevel.HasValue))
                model.Subscription = subscriber.SubscriptionLevel.Value;
            else
                model.Subscription = -1;

            return PartialView(model);
        }

        [HttpPost]
        public ActionResult EditSubscriptionInfo(EditSubscriptionInfoViewModel model)
        {
            if (ModelState.IsValid)
            {
                Subscriber subscriber = _subscriberService.Get(model.ID);
                
                // unsubscribed
                if (model.Subscription == -1)
                {
                    subscriber.SmmUnsubscribed = true;
                    subscriber.SubscriptionLevel = null;
                    subscriber.EndDate = null;
                }
                else
                {
                    subscriber.SmmUnsubscribed = false;
                    subscriber.ProductType = (byte)(subscriber.ProductType | (byte)ProductType.SelfMadeMillionaire);
                    subscriber.SubscriptionLevel = (byte)model.Subscription;
                    if (subscriber.IsFreeSMMSubscriber())
                        subscriber.EndDate = null;
                    else
                        subscriber.EndDate = model.ExpirationDate;
                }
                _subscriberService.Update(subscriber);
                return Json(new { success = true }, JsonRequestBehavior.AllowGet);
            }

            return PartialView(model);   
        }

        [HttpPost]
        public ActionResult BuyProduct(int id, byte producttype)
        {
            string message = "Payment Successfully Applied";
            Subscriber subscriber = _subscriberService.Get(id);

            _subscriberService.OrderWithPayment(subscriber.Email, producttype);
            
            return Json(new { message }, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public ActionResult UnsubscribeSMM(int id)
        {
            string message = "Unsubscribed Successfully";

            Subscriber subscriber = _subscriberService.Get(id);
            subscriber.SmmUnsubscribed = true;
            subscriber.SubscriptionLevel = (int)SubscriptionType.Free;
            _subscriberService.Update(subscriber);
                        
            return Json(new { message }, JsonRequestBehavior.AllowGet);
        }


        [HttpPost]
        public ActionResult SubscribeMMM(int id)
        {
            string message = "Subscribed successfull";

            Subscriber subscriber = _subscriberService.Get(id);
            subscriber.MmmUnsubscribed = false;
            _subscriberService.Update(subscriber);
            
            return Json(new { message }, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public ActionResult SubscribeSMMFree(int id)
        {
            string message = "Subscribed Successfully";

            Subscriber subscriber = _subscriberService.Get(id);
            subscriber.SmmUnsubscribed = false;
            subscriber.SubscriptionLevel = (int)SubscriptionType.Free;
            _subscriberService.Update(subscriber);
            
            return Json(new { message }, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public ActionResult UnsubscribeMMM(int id)
        {
            string message = "Unsubscribed Successfully";

            Subscriber subscriber = _subscriberService.Get(id);
            subscriber.MmmUnsubscribed = true;
            _subscriberService.Update(subscriber);
                        
            return Json(new { message }, JsonRequestBehavior.AllowGet);
        }

        
        public ActionResult BalanceDue()
        {
            //var order = _subscriberService.GetOrder(id);
            var model = new BallanceDueViewModel();
            //model.CostDue = order.Price;
            //model.ProductName = _subscriberService.GetProducts(order.Subscriber).First(x => x.Id == order.ProductId).ProductName;

            return PartialView(model);
        }
	}
}
